package cn.ucox.web.ms;

import cn.ucox.web.ms.components.cache.LoadMetaInfoData;
import cn.ucox.web.ms.components.ftp.DexFtpClient;
import cn.ucox.web.ms.components.ftp.FTPClientPool;
import cn.ucox.web.ms.components.ftp.FtpConfig;
import cn.ucox.web.ms.config.DataExchangeConfig.DexRedisConfig;
import cn.ucox.web.ms.config.DataExchangeConfig.ExchangeConfig;
import cn.ucox.web.ms.config.DataExchangeConfig.FtpConfigHub;
import cn.ucox.web.ms.config.DataExchangeConfig.PollingConfig;
import cn.ucox.web.ms.monitor.FtpDirectoryListener;
import cn.ucox.web.ms.monitor.SyncFileParser;
import cn.ucox.web.ms.monitor.SyncFileParserSMHS;
import cn.ucox.web.ms.packer.TransactionDataSlicer;
import cn.ucox.web.ms.persistence.PersistenceQueueListener;
import cn.ucox.web.ms.plugin.FastFSFilePersistence;
import cn.ucox.web.ms.plugin.PostgresDataPersistence;
import cn.ucox.web.ms.polling.BucketDataProcessor;
import cn.ucox.web.ms.polling.DataScanner;
import cn.ucox.web.ms.polling.IDataLoader;
import cn.ucox.web.ms.redis.RedisClient;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.pool2.PooledObject;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import redis.clients.jedis.Jedis;

import javax.annotation.Resource;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;

import static cn.ucox.web.ms.Constant.*;

/**
 * @author chenw
 * @create 2017-06-06 17:32
 * @email javacspring@gmail.com
 */
public class DexBootstrap {

    private ConfigurableApplicationContext context;

    private RedisClient redisClient = RedisClient.instance();

    private DataScanner scanner;
    private TransactionDataSlicer transactionDataSlicer;
    private FtpDirectoryListener ftpDirectoryListener;
    private SyncFileParserSMHS syncFileParser;
    private PersistenceQueueListener persistenceQueueListener;

    private DexFtpClient dexFtpClient;

    public DexBootstrap(ConfigurableApplicationContext context) {
        this.context = context;
    }

    public void start()  {
        if (null == context)
            throw new RuntimeException("请先调用init()方法初始化");
        //Redis配置
        DexRedisConfig redisConfig = context.getBean(DexRedisConfig.class);
        redisClient.init(redisConfig);
        //数据同步配置信息
        ExchangeConfig exchangeConfig = context.getBean("exchangeConfig", ExchangeConfig.class);
        //初始化Redis相关数据
        //initSyncAnchor();
        //初始化统计信息表
        //initSyncStatistics();
        //初始化同步表信息
        //initSyncTablesMetaInfo();
        // 初始化本地备份目录、异常目录
        initFileDir(exchangeConfig);
        FtpConfigHub ftpConfigHub = context.getBean("ftpConfigHub", FtpConfigHub.class);
        //启动同步扫描组件
        //BucketDataProcessor processor = context.getBean(BucketDataProcessor.class);
        //数据轮询配置
        PollingConfig pollingConfig = context.getBean(PollingConfig.class);
        //数据加载组件
        //IDataLoader dataLoader = context.getBean(IDataLoader.class);
        //scanner = new DataScanner(pollingConfig, dataLoader, processor);
        //scanner.start();
        //检测内网FTP文件并做内网人口库及腾讯照片识别功能
        FtpConfig outInWrite1Config = ftpConfigHub.getFtpConfig("wjwsmhsout");
//        transactionDataSlicer = new TransactionDataSlicer(outInWrite1Config, new DexFtpClient(outInWrite1Config));
//        transactionDataSlicer.setExchangeConfig(exchangeConfig);
//        transactionDataSlicer.start();
        //启动数据处理组件
        //启动FTP状态监控组件
        FtpConfig outInRead1 = ftpConfigHub.getFtpConfig("wjwsmhsin");

        ftpDirectoryListener = new FtpDirectoryListener(new DexFtpClient(outInRead1),pollingConfig);
        ftpDirectoryListener.initFTPMonitor();
        ftpDirectoryListener.start();

        //启动FTP文件解析组件
        syncFileParser = new SyncFileParserSMHS(new DexFtpClient(outInRead1),new DexFtpClient(outInWrite1Config));
        syncFileParser.setExchangeConfig(exchangeConfig);
        syncFileParser.start();
        //数据持久化组件
//        JdbcTemplate jdbcTemplate = context.getBean("persistenceJdbcTemplate", JdbcTemplate.class);
        //数据持久化组件
//        FastFileStorageClient storageClient = context.getBean("defaultFastFileStorageClient",FastFileStorageClient.class);
//        persistenceQueueListener = new PersistenceQueueListener();
//        persistenceQueueListener.setAttachmentPersistence(new FastFSFilePersistence(jdbcTemplate, storageClient));
//        persistenceQueueListener.setDataPersistence(new PostgresDataPersistence(jdbcTemplate));
//        persistenceQueueListener.start();
    }

    /**
     * 初始化同步表元数据信息
     */
    private void initSyncTablesMetaInfo() {
        ExchangeConfig exchangeConfig = context.getBean("exchangeConfig", ExchangeConfig.class);
        JdbcTemplate jdbcTemplate = context.getBean("pollingJdbcTemplate", JdbcTemplate.class);
        PollingConfig pollingConfig = context.getBean("pollingConfig", PollingConfig.class);
        new LoadMetaInfoData(jdbcTemplate, exchangeConfig, pollingConfig).loadData();
    }

    private void initFileDir(ExchangeConfig exchangeConfig){
        File file1 = new File(exchangeConfig.getSendBackup());
        if (!file1.exists() || !file1.isDirectory()) {
            file1.mkdirs();
        }
        File file2 = new File(exchangeConfig.getSendError());
        if (!file2.exists() || !file2.isDirectory()) {
            file2.mkdirs();
        }
        File file3 = new File(exchangeConfig.getReceiveBackup());
        if (!file3.exists() || !file3.isDirectory()) {
            file3.mkdirs();
        }
        File file4 = new File(exchangeConfig.getReceiveError());
        if (!file4.exists() || !file4.isDirectory()) {
            file4.mkdirs();
        }
    }


    /**
     * 数据同步平台调用此方法时通知全部组件安全停止运行
     */
    public void stop() {
        if (null != scanner) {
            scanner.stop();
            scanner = null;
        }
        if (null != transactionDataSlicer) {
            transactionDataSlicer.stop();
            transactionDataSlicer = null;
        }
        if (null != ftpDirectoryListener) {
            ftpDirectoryListener.stop();
            ftpDirectoryListener = null;
        }
        if (null != syncFileParser) {
            syncFileParser.stop();
            syncFileParser = null;
        }
        if (null != persistenceQueueListener) {
            persistenceQueueListener.stop();
            persistenceQueueListener = null;
        }
    }

    /**
     * 初始化统计日报
     */
    private void initSyncStatistics() {
        redisClient.hset("SYNC:STATISTICS:DAY".getBytes(), "2017-06-07".getBytes(), "".getBytes());
    }

    /**
     * 初始化统计锚点
     */
    private void initSyncAnchor() {
        redisClient.hmsetx(SYNC_ANCHOR_BYTE, new HashMap<byte[], byte[]>() {{
            put(SYNC_ANCHOR_TRANSACTION_ID_BYTE, "100000000".getBytes());
            put(SYNC_ANCHOR_SYNC_TASK_START_TIME_BYTE, "0".getBytes());
            put(SYNC_ANCHOR_SYNC_TASK_END_TIME_BYTE, "0".getBytes());
            put(SYNC_ANCHOR_SYNC_DATA_START_TIME_BYTE, "0".getBytes());
            put(SYNC_ANCHOR_SYNC_DATA_END_TIME_BYTE, "0".getBytes());
            put(SYNC_ANCHOR_TOTAL_TASK_NUM_BYTE, "0".getBytes());
            put(SYNC_ANCHOR_TASK_DONE_NUM_BYTE, "0".getBytes());
            put(SYNC_ANCHOR_TRANSACTION_DONE_BYTE, "Y".getBytes());
            put(SYNC_ANCHOR_TRANSACTION_DATA_ROWS_BYTE, "0".getBytes());
            put(SYNC_ANCHOR_TRANSACTION_DATA_SIZE_BYTE, "0".getBytes());

            put(SYNC_MSST_BYTE, "0".getBytes());
            put(SYNC_MSET_BYTE, "0".getBytes());
            put(SYNC_MDST_BYTE, "0".getBytes());
            put(SYNC_MDET_BYTE, "0".getBytes());

            put(SYNC_LSST_BYTE, "0".getBytes());
            put(SYNC_LSET_BYTE, "0".getBytes());
            put(SYNC_LDST_BYTE, "0".getBytes());
            put(SYNC_LDET_BYTE, "0".getBytes());
        }});
    }
}
